/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2006
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package br.ufmg.dees.insane.analysisModel;

import java.util.ArrayList;

import br.ufmg.dees.insane.util.IMatrix;
import br.ufmg.dees.insane.util.IPoint3d;
import br.ufmg.dees.insane.util.IVector;
import br.ufmg.dees.insane.util.pointValues.PointValues;
import br.ufmg.dees.insane.util.pointValues.StringPointValues;

/**
*A class representing a PlaneTruss analysis model of a FrameElement.
*
*@author Fonseca, Flavio & Pitangueira, Roque
*@version 1.1
*@since September 2003, modified October 2006
*/
public class PlaneTruss extends FrameElmAnalysis {

	private static final long serialVersionUID = 1L;

	public PlaneTruss() {
	}
	
	public IMatrix getInternalVariableOperator(IMatrix d, IMatrix d2, IVector n, IMatrix c) {
		IMatrix b = new IMatrix(1,4);
		b.setElement(0,0, d.getElement(0,0));
		b.setElement(0,2, d.getElement(1,0));
		return b;
	}
	
	public IMatrix getInternalVariableOperator(IMatrix d, IMatrix d2, IMatrix d3, IVector n, IMatrix c) {
		return this.getInternalVariableOperator(d, d2, n, c);
	}
	
	public IMatrix getInternalVariableOperator(IMatrix d, IMatrix d2, IVector n, IMatrix c, IMatrix u) {
		return this.getInternalVariableOperator(d, d2, n, c);
	}

	public IMatrix getDualInternalVariableOperator(IMatrix e) {
		//Matrix e must be FrameElement.getPropertiesMatrix()
		IMatrix d = new IMatrix(1,1);
		d.setElement(0, 0, e.getElement(1, 0)*e.getElement(7, 0));
		return d;
	}

	public IMatrix getStateVariableOperator(IMatrix n2, IVector n1, IMatrix c) {
		if (n2 == null) {
			n2 = new IMatrix(2,1);
		}
		
		IMatrix n = new IMatrix(2, 4);
		n.setZero();
		n.setElement(0, 0, n1.getElement(0));
		n.setElement(1, 1, n1.getElement(0));
		n.setElement(0, 2, n1.getElement(1));
		n.setElement(1, 3, n1.getElement(1));
		return (n);
	}

	public int getNumberOfInternalVariables() {
		return 1;
	}

	public int getNumberOfDualInternalVariables() {
		return 1;
	}

	public String[] getInternalVariablesLabels() {
		String[] Dlabels = {"Ea"};
        return Dlabels;
	}

	public String[] getDualInternalVariablesLabels() {
		String[] Dlabels = {"Nx"};
        return Dlabels;
	}

	public String getLabel() {
		return "PlaneTruss";
	}

	public IMatrix getTransformationMatrix(IMatrix dl, IMatrix cN) {
		
		//Calculating element length, cos and sin
		IPoint3d point1 = new IPoint3d(cN.getElement(0,0), cN.getElement(0,1), cN.getElement(0,2));
		IPoint3d point2 = new IPoint3d(cN.getElement(1,0), cN.getElement(1,1), cN.getElement(1,2));
		double l = point1.distance(point2);
		double sin = (cN.getElement(1,1) - cN.getElement(0,1)) / l;
		double cos = (cN.getElement(1,0) - cN.getElement(0,0)) / l;
		
		//"Default" transformation matrix
		IMatrix t = new IMatrix (4, 4);
		t.setElement(0,0, cos);
		t.setElement(0,1, sin);
		t.setElement(1,0, -sin);
		t.setElement(1,1, cos);
		t.setElement(2,2, cos);
		t.setElement(2,3, sin);
		t.setElement(3,2, -sin);
		t.setElement(3,3, cos);
		
		return t;
	}

	public ArrayList getDOFLabels(int n) {
		ArrayList <PointValues> al = new ArrayList<PointValues>();
		PointValues spv = new StringPointValues();
	    spv.addPointValue("Dx");
	    spv.addPointValue("Dy");
		for(int i=0; i<n; i++) {
			al.add(i,spv);
		}
		return al;
	}

	@Override
	public IMatrix getLocalStiffnessMatrix(double[] properties) {
		IMatrix mat = new IMatrix(4,4);
		mat.setZero();
		
		double l = properties [0];
		double e = properties[1];
		double a = properties[7];
		
		//Setting the value of factor = (A*E/L)
		double factor = a * e / l;
		
		//Setting the value of the matrix
		mat.setElement(0, 0, factor);
		mat.setElement(0, 2, -factor);
		mat.setElement(2, 0, -factor);
		mat.setElement(2, 2, factor);
		
		return (mat);
	}

	@Override
	public IMatrix nodalRotationMatrix(double angle1, double angle2) {
		IMatrix mat = new IMatrix(4,4);
		double ia = angle1 * Math.PI / 180;
		double fa = angle2 * Math.PI / 180;
		mat.setElement(0, 0, Math.cos(ia));
		mat.setElement(0, 1, Math.sin(ia));
		mat.setElement(1, 0, -Math.sin(ia));
		mat.setElement(1, 1, Math.cos(ia));
		mat.setElement(2, 2, Math.cos(fa));
		mat.setElement(2, 3, Math.sin(fa));
		mat.setElement(3, 2, -Math.sin(fa));
		mat.setElement(3, 3, Math.cos(fa));
		return (mat);
	}

	public ArrayList getDOFLabels() {
		// TODO Auto-generated method stub
		return null;
	}

	public IMatrix getPMatrix() {
		// TODO Auto-generated method stub
		return null;
	}

}
